package com.Maykk.Demo01;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @ClassName: Demo06
 * @Description: TODO 通过反射 获取 Student 类中的成员属性
 * @Author: MaykkStar@163.com
 */
public class Demo05 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        Class<Student> stuClass = Student.class;
        // 实例化 Student 类对象
        Student stu = stuClass.getDeclaredConstructor().newInstance();

        /**
         *  获取成员属性的集合
         */

        // 获取所有共有的成员属性
        // Field[] fields = stuClass.getFields();
        // for (Field field : fields) {
        //     System.out.println(field);
        // }

        // 获取所有成员属性（包括所有权限的成员属性）
        // Field[] dFields = stuClass.getDeclaredFields();
        // for (Field dField : dFields) {
        //     System.out.println(dField);
        // }

        /**
         * 获取单独的成员属性
         */

        // 获取公有成员属性 name
        // Field name = stuClass.getField("name");
        // System.out.println(name);

        // 获取私有的成员属性 age
        Field age = stuClass.getDeclaredField("age");
        // System.out.println(age);

        // 设置对象中的成员属性 age 的值

        // 此时符合 Student 中的 setAge 的条件
        // stu.setAge(18);

        // 此时不符合 Student 中的 setAge 的条件
        // stu.setAge(199);

        // age.setAccessible(true); // Student 类中的 age 为 private, 所以需要抑制权限
        // age.set(stu,1888); // 通过 Field 类的 set 方法可以抑制 Student 类中的限制
        // System.out.println(stu.getAge());
        // System.out.println(age.get(stu));

        // 获取、设置name 的值
        // Field name = stuClass.getField("name");
        // name.set(stu,"Maykk");
        // System.out.println(name.get(stu));

        /**
         * 获取类中的成员方法
         */
        // 获取当前类中的所有方法，包括父类中继承下来的方法
        // Method[] methods = stuClass.getMethods();
        // for (Method method : methods) {
        //     System.out.println(method);
        // }

        // 获取当前类中的所有方法，包含非公有，但是不包含父类继承下来的方法
        // Method[] dMethods = stuClass.getDeclaredMethods();
        // for (Method dMethod : dMethods) {
        //     System.out.println(dMethod);
        // }

        // 无参公有成员方法
        // Method methodPub01 = stuClass.getMethod("methodPub");
        // stu.methodPub();
        // 通过成员方法对象，调用 invoke 方法，第一个参数为调用哪个对象中的方法，后面的参数为成员方法的实参
        // methodPub01.invoke(stu);
        // 带参公有成员方法
        // Method methodPub02 = stuClass.getMethod("methodPub",String.class);
        // stu.methodPub("我是参数");
        // methodPub02.invoke(stu,"我是参数");


        // 无参私有成员方法
        Method methodPri01 = stuClass.getDeclaredMethod("methodPri");
        methodPri01.setAccessible(true);
        methodPri01.invoke(stu);

        // 带参私有成员方法
        Method methodPri02 = stuClass.getDeclaredMethod("methodPri", String.class);
        methodPri02.setAccessible(true);
        methodPri02.invoke(stu, "我是参数");

        // 带参私有成员方法


        System.out.println("=====================================");
        System.out.println(stu);
    }
}
